
#include <stdio.h>

static inline void __check(char *a) { }

#define to_var(x)           ((unsigned long)(void *)(x) > 0xFF ? *(int *)(x) : 0xFF)
#define to_off(base, x)     ((unsigned long)(x) - (unsigned long)(base))

#define __pr(base, a) \
    do { \
        __check(a); \
        printf("| %-16s|        | %p | 0x%02lX | 0x%02X |\n", \
                #a, (void *)(a), to_off(base, a), to_var(a)); \
    } while (0)


int main(void)
{
    unsigned long size;
    int i, j;
    int a1[8];
    int a2[4][8];

    for (i = 0; i < 8; i++) {
        a1[i] = i;
    }
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 8; j++) {
            a2[i][j] = (i << 4) | j;
        }
    }

    size = (unsigned long)sizeof(a1);
    printf("sizeof(a1): %lu(0x%lX)\n", size, size);
    printf("| var    | typeof(var) | (void *)(var)   | offset  | *(int *)(var) |\n");
    printf("| :------| :---------- | :-------------- | :-----: | :-----------: |\n");

    __pr(a1, a1);

    __pr(a1, &a1);
    __pr(a1, &a1[0]);

    __pr(a1, a1 + 1);
    __pr(a1, &a1 + 1);
    __pr(a1, &a1[0] + 1);


    size = (unsigned long)sizeof(a2);
    printf("sizeof(a2): %lu(0x%lX)\n", size, size);
    printf("| var    | typeof(var) | (void *)(var)   | offset  | *(int *)(var) |\n");
    printf("| :------| :---------- | :-------------- | :-----: | :-----------: |\n");

    __pr(a2, a2);
    __pr(a2, a2[0]);

    __pr(a2, &a2);
    __pr(a2, &a2[0]);
    __pr(a2, &a2[0][0]);

    __pr(a2, a2 + 1);
    __pr(a2, a2[0] + 1);

    __pr(a2, &a2 + 1);
    __pr(a2, &a2[0] + 1);
    __pr(a2, &a2[0][0] + 1);

    __pr(a2, (a2 + 1) + 1);
    __pr(a2, (&a2 + 1) + 1);
    __pr(a2, (&a2[0] + 1) + 1);

    return 0;
}
